package swingExtended.customTextPane;

import java.awt.Color;
import java.awt.Font;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import processorIO.FileIO;
import swingExtended.SwingExtended;

/**
 *
 * @author Shimu
 */
public class SimpleTextPane extends javax.swing.JTextPane {

    // <editor-fold defaultstate="collapsed" desc="Public Static Variables">
    public static final String DEFAULT_ENCODING = "UTF-8";
    //public static final String DEFAULT_ENCODING = "fail";

    /** The default compatibleFont used for all text */
    public static final String DEFAULT_FONT = "Arial Unicode MS";

    /** The default style used for all text */
    public static final int DEFAULT_STYLE = Font.PLAIN;

    /** The default size used for all text */
    public static final int DEFAULT_SIZE = 12;

    /** The String used to replace characters that could not be displayed */
    public static final String REPLACEMENT_CHAR = "[?]";
    // The names of a few common fonts

    /** The String that represents the Font Times New Roman */
    public static final String TIMES_NEW_ROMAN = "Times New Roman";

    /** The String that represents the Font Arial */
    public static final String ARIAL = "Arial";

    /** The String that represents the Font Arial Black */
    public static final String ARIAL_BLACK = "Arial Black";
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Private Instance Variables">
    private final ArrayList<CustomTextPaneListener> LISTENERS = 
            new ArrayList<CustomTextPaneListener>();
    
    private int MAX_LENGTH = 30000;

    private boolean findCompatibleFont = false;

    private Color color = Color.BLACK;

    private BufferedWriter writer;
    // </editor-fold>

    /** Creates new form ProgressPanel */
    public SimpleTextPane() {
    }

    // <editor-fold defaultstate="collapsed" desc="Getters/Setters">
    public Color getColor() {
        return color;
    }

    public void setColor(Color newColor) {
        this.color = newColor;
    }

    /**
     * @return the findCompatibleFont
     */
    public boolean willFindCompatibleFont() {
        return findCompatibleFont;
    }

    /**
     * @param findCompatibleFont the findCompatibleFont to set
     */
    public void setFindCompatibleFont(boolean findCompatibleFont) {
        this.findCompatibleFont = findCompatibleFont;
    }

    public void setOutputUrl(String url) throws UnsupportedEncodingException,
            FileNotFoundException, IOException {
        // Close the previous writer
        if (writer != null) {
            closeWriter();
        }
        writer = FileIO.getFileWriter(url, false, DEFAULT_ENCODING);
    }

    public void closeWriter() throws IOException {
        writer.close();
        writer = null;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Add/Change text">
    /**
     * Clears the text area.
     */
    public void clearPane() {
        // Clears the text area
        this.setText("");
    }

    /**
     * Prints the given message to the screen using the default compatibleFont and color. Adds
     * a newline character at the end of the message.
     * @param msg 
     */
    public void println(String msg) {
        this.print(msg);
        this.print("\n");
    }

    /**
     * Prints the given msg to the screen using the given preferredFontName and color.
     * @param msg the message to be printed to the screen
     * @param preferredFontName the preferredFontName of the message
     * @param c the color of the message
     * @return true if the writing was successful, false otherwise.
     */
    public void print(String msg) {
        final StyleContext STYLE_CONTEXT = StyleContext.getDefaultStyleContext();
        AttributeSet aset = STYLE_CONTEXT.addAttribute(
                SimpleAttributeSet.EMPTY, StyleConstants.Foreground, this.getColor());
        aset = STYLE_CONTEXT.addAttribute(aset, StyleConstants.Alignment,
               StyleConstants.ALIGN_JUSTIFIED);

        this.output(msg, aset);
        this.validate();
    }
    // </editor-fold>

    protected void output(String msg, AttributeSet aset) {
        Document doc = this.getDocument();
        if (doc.getLength() < MAX_LENGTH) {
            try {
                doc.insertString(doc.getLength(), msg, aset);
            } catch (BadLocationException ex) {
                System.err.println("Bad location when inserting text into document");
                // do nothing    
            }
            for (CustomTextPaneListener listener : LISTENERS) {
                listener.onAddText(msg, this);
            }
        } else {
            //System.err.println(doc.getLength());
        }
        if (writer != null) {
            try {
                writer.write(msg);
            } catch (IOException e) {
                SwingExtended.openWarningWindow(this, String.format(
                        "An error occurred while writing to file: %s\n. "
                        + "Most likely because the file is being opened by another program. "
                        + "Close the program then press OK", e.getLocalizedMessage()));

            }
        }
    }
        
    public void addListener(CustomTextPaneListener listener) {
        this.LISTENERS.add(listener);
    }
}
